# From: http://www.panda3d.org/forums/viewtopic.php?t=2487&postdays=0&postorder=asc&start=30
# courtesy of steego with mods by gomtuu plus some additions of my own

import sys

import wx

from pandac.PandaModules import WindowProperties
from direct.showbase import DirectObject

import pvis_main

class PandaPanel(wx.Panel):
    def __init__(self, *args, **kwargs):
        wx.Panel.__init__(self, *args, **kwargs)
        # Frame must be shown before the panel can be initialized
        # I'm trying to avoid forcing the user to do this in their own code.
        # TODO: I'm not sure that this panel is behaving like a regular panel
        # need to do some testing to see if it can be put in a sizer etc.
        # There may be a better way to implement this stuff
        parentFrame = self
        while not isinstance(parentFrame, wx.Frame):
            parentFrame = parentFrame.GetParent()
        
        # The frame that this panel is on has to be showing
        # before the init or it will fail.
        parentFrame.Show()

        self.initialize()

        # Binding to EVT_SHOW does not work because the event is not 
        # triggered until after panda's run() is called and the camera
        # setup requires the window to exist already. And even without that
        # it seems to not work.  As best as I can tell we need to have
        # the wx python side up and running before run() is called.
        #self.Bind(wx.EVT_SHOW, self.OnShow)
        #self._initialized = False

    #def OnShow(self, event):
        #if not self._initialized:
            #self.initialize()
        
    def initialize(self):
        assert self.GetHandle() != 0
        wp = WindowProperties()
        wp.setOrigin(0,0)
        wp.setSize(self.ClientSize.GetWidth(), self.ClientSize.GetHeight())
        wp.setParentWindow(self.GetHandle())
        pvis_main.base.openDefaultWindow(props = wp, gsg = None) #@UndefinedVariable -- openDefaultWindow()
        self.Bind(wx.EVT_SIZE, self.OnResize)
        #self._initialized = True
        
    def OnResize(self, event):
        # TODO: For some reason this is not working right with sizers
        panel_size = event.GetSize() 
        wp = WindowProperties()
        wp.setOrigin(0,0)
        wp.setSize(panel_size.GetWidth(), panel_size.GetHeight())
        pvis_main.base.win.requestProperties(wp) #@UndefinedVariable -- win

class PandaFrame(wx.Frame):
    """A frame with a PandaPanel which takes up its entire client area.
    Use of this class is optional, you can make your own frame class
    and add the PandaPanel to it however you want."""
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)
        self.pandapanel = PandaPanel(self, wx.ID_ANY, size=self.ClientSize)

class PandaApp(wx.App, DirectObject.DirectObject):
    def __init__(self):
        wx.App.__init__(self)
        self.eventLoop = wx.EventLoop() 
        wx.EventLoop.SetActive(self.eventLoop)
        pvis_main.taskMgr.add(self.WxStep, "wxEventLoopTask")
        self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy)         

    def OnDestroy(self, Event):
        try:
            pvis_main.base
        except NameError:
            sys.exit()
        pvis_main.base.userExit() #@UndefinedVariable -- userExit()
    
    def WxStep(self, Task):
        # Plow through all the events before releasing back to Panda3d
        while self.Pending():
            self.Dispatch()
            
        self.ProcessIdle()
        return Task.cont
